home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 350_01 / pcx_disp.c < prev    next >
C/C++ Source or Header  |  1991-11-29  |  40KB  |  1,141 lines

  1. /*
  2.  *************************************************************************
  3.  *
  4.  *  PCX_DISP.C - PCX_LIB Library Image Display Functions
  5.  *
  6.  *  Version:    1.00C
  7.  *
  8.  *  History:    91/02/14 - Created
  9.  *              91/04/01 - Release 1.00A
  10.  *              91/04/03 - Fixed "segread" call.
  11.  *              91/04/07 - Release 1.00B
  12.  *              91/11/18 - Fixed "pcx_set_palette" for large memory model.
  13.  *              91/12/01 - Release 1.00C
  14.  *
  15.  *  Compiler:   Microsoft C V6.0
  16.  *
  17.  *  Author:     Ian Ashdown, P.Eng.
  18.  *              byHeart Software
  19.  *              620 Ballantree Road
  20.  *              West Vancouver, B.C.
  21.  *              Canada V7S 1W3
  22.  *              Tel. (604) 922-6148
  23.  *              Fax. (604) 987-7621
  24.  *
  25.  *  Copyright:  Public Domain
  26.  *
  27.  *************************************************************************
  28.  */
  29.  
  30. /*
  31.  *************************************************************************
  32.  *
  33.  *  PORTABILITY NOTES
  34.  *
  35.  *  1.  While this program is written in ANSI C, it uses a number of 
  36.  *      function calls that are specific to the Microsoft C V6.0 library.
  37.  *      These are documented as follows for the purposes of porting this
  38.  *      program to other compilers and/or processors: 
  39.  *
  40.  *          _ffree              - "free" for small model / far data
  41.  *          _fmalloc            - "malloc" for small model / far data
  42.  *          _fmemcpy            - "memcpy" for small model / far data
  43.  *          int86               - execute 80x86 interrupt routine
  44.  *          int86x              - execute 80x86 interrupt routine (far
  45.  *                                data)
  46.  *          _remapallpalette    - remap entire video display color palette
  47.  *          _selectpalette      - select CGA color palette
  48.  *          outpw               - output word to 80x86 I/O port
  49.  *
  50.  *  2.  When porting this program to other processors, remember that words
  51.  *      are stored by 80x86-based machines in the big-endian format.  That
  52.  *      is, the eight least significant bits (lower byte) are stored
  53.  *      first, followed by the eight most significant bits (upper byte).
  54.  *      If PCX-format files are transferred to little-endian machines
  55.  *      (such as those based on 680x0 and Z8000 processors), the order of
  56.  *      bytes within each word will have to be reversed before they can 
  57.  *      be interpreted.  (This applies to the file header only, since the
  58.  *      encoded image data and optional 256-color palette are stored as
  59.  *      bytes.)
  60.  *
  61.  * 3.   MS-DOS does not recognize the 720 x 348 graphics mode of the
  62.  *      Hercules monochrome display adapter.  Therefore, the constant
  63.  *      PCX_HERC should never be passed as a video mode parameter to any
  64.  *      BIOS service routine.
  65.  *
  66.  *      The Microsoft C compiler includes a "video mode" parameter
  67.  *      definition (_HERCMONO) that is defined as 0x08.  This is a
  68.  *      reserved MS-DOS video mode that is apparently used internally by
  69.  *      the ROM BIOS.  It can, however, be passed to the Microsoft C
  70.  *      library function "_setvideomode" to force the Hercules display
  71.  *      adapter into graphics mode.
  72.  *
  73.  *      Most other MS-DOS C compilers offer similar library functions to
  74.  *      force the Hercules monochrome display adapter into its 720 x 348
  75.  *      graphics mode.
  76.  *
  77.  ************************************************************************* 
  78.  */
  79.  
  80. /*      INCLUDE FILES                                                   */
  81.  
  82. #include <stdio.h>
  83. #include <stdlib.h>
  84. #include <string.h>
  85. #include <conio.h>
  86. #include <dos.h>
  87. #include <malloc.h>
  88. #include <graph.h>
  89. #include "pcx_int.h"
  90.  
  91. /*      FORWARD REFERENCES                                              */
  92.  
  93. static BOOL pcx_read_init(PCX_WORKBLK *, int, int);
  94. static BOOL pcx_read_extpal(PCX_WORKBLK *);
  95. static BOOL pcx_read_header(PCX_WORKBLK *);
  96. static BOOL pcx_read_line(PCX_WORKBLK *, unsigned char *, int);
  97. static BOOL pcx_set_palette(PCX_PAL *, int);
  98.  
  99. static void pcx_cga_palette(PCX_PAL *, int);
  100. static void pcx_put_cga(PCX_WORKBLK *, unsigned char _far *, int);
  101. static void pcx_put_ega(PCX_WORKBLK *, unsigned char _far *, int);
  102. static void pcx_put_herc(PCX_WORKBLK *, unsigned char _far *, int);
  103. static void pcx_put_vga(PCX_WORKBLK *, unsigned char _far *, int);
  104.  
  105. /*      GLOBALS                                                         */
  106.  
  107. /*      PUBLIC FUNCTIONS                                                */
  108.  
  109. /*
  110.  *************************************************************************
  111.  *
  112.  *  PCX_READ - Read PCX Image File
  113.  *
  114.  *  Purpose:    To read and display a PCX-format image file.
  115.  *
  116.  *  Setup:      BOOL pcx_read
  117.  *              (
  118.  *                char *fname,
  119.  *                int vmode,
  120.  *                int page
  121.  *              )
  122.  *
  123.  *  Where:      fname is a PCX image file name.
  124.  *              vmode is the MS-DOS video mode.  Valid values are:
  125.  *
  126.  *                PCX_HERC -    720 x 348 Hercules monochrome
  127.  *                0x04 -        320 x 200 4-color CGA
  128.  *                0x05 -        320 x 200 4-color CGA (color burst off)
  129.  *                0x06 -        640 x 200 2-color CGA
  130.  *                0x0d -        320 x 200 16-color EGA/VGA
  131.  *                0x0e -        640 x 200 16-color EGA/VGA
  132.  *                0x0f -        640 x 350 2-color EGA/VGA
  133.  *                0x10 -        640 x 350 16-color EGA/VGA
  134.  *                0x11 -        640 x 480 2-color VGA
  135.  *                0x12 -        640 x 480 16-color VGA
  136.  *                0x13 -        320 x 200 256-color VGA
  137.  *
  138.  *              page is the video display page number.  Valid values are:
  139.  *
  140.  *                Mode PCX_HERC - 0 or 1
  141.  *                Mode 0x0d     - 0 to 7
  142.  *                Mode 0x0e     - 0 to 3
  143.  *                Mode 0x0f     - 0 or 1
  144.  *                Mode 0x10     - 0 or 1
  145.  *                All Other     - 0
  146.  *
  147.  *  Return:     TRUE if successful; otherwise FALSE.
  148.  *
  149.  *  Note:       The video display adapter must be in the appropriate mode
  150.  *              and active page for the image to be displayed.
  151.  *
  152.  *************************************************************************
  153.  */
  154.  
  155. BOOL pcx_read
  156. (
  157.   char *fname,
  158.   int vmode,
  159.   int page
  160. )
  161. {
  162.   int bpline;                   /* Number of bytes per scan line        */
  163.   int line_num;                 /* Scan line number                     */
  164.   int max_lines;                /* Maximum number of scan lines         */
  165.   unsigned char *linep;         /* PCX scan line buffer pointer         */
  166.   BOOL status = TRUE;           /* Return status                        */
  167.   PCX_WORKBLK *wbp;             /* PCX image file workblock pointer     */
  168.  
  169.   /* Open a PCX image file workblock                                    */
  170.  
  171.   if ((wbp = pcx_open(fname, FALSE)) == (PCX_WORKBLK *) NULL)
  172.     return (FALSE);
  173.  
  174.   /* Initialize the workblock for reading                               */
  175.  
  176.   if (pcx_read_init(wbp, vmode, page) == FALSE)
  177.   {
  178.     (void) pcx_close(wbp);      /* Close the PCX workblock              */
  179.     return (FALSE);
  180.   }
  181.  
  182.   /* Calculate the image height                                         */
  183.  
  184.   max_lines = wbp->header.yul + wbp->header.ylr + 1;
  185.  
  186.   /* Calculate number of bytes per line (for all color planes)          */
  187.  
  188.   bpline = wbp->header.bppscan * wbp->header.nplanes;
  189.  
  190.   /* Allocate the PCX scan line buffer                                  */
  191.  
  192.   if ((linep = (unsigned char *) malloc(bpline)) != (unsigned char *)
  193.       NULL)
  194.   {
  195.     /* Set the file pointer to the beginning of the encoded image data  */
  196.  
  197.     if (status == TRUE)
  198.       if (fseek(wbp->fp, (long) (sizeof(PCX_HDR)), SEEK_SET) != 0)
  199.         status = FALSE;
  200.  
  201.     /* Set the video display adapter color palette unless the PCX file  */
  202.     /* is Version 3.0 (i.e. - PC Paintbrush Version 2.8 w/o palette)    */
  203.  
  204.     if (status == TRUE)
  205.       if (wbp->header.version != 3)
  206.         if (pcx_set_palette(wbp->palettep, vmode) == FALSE)
  207.           status = FALSE;
  208.  
  209.     /* Read the image line by line